import 'dart:io';

import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';

/// 权限帮助类
class PermissionHelper {
  static final PermissionHelper _permissionHelper =
      PermissionHelper._internal();

  factory PermissionHelper.instance() {
    return _permissionHelper;
  }

  PermissionHelper._internal();

  /// 检查并请求权限，如果没有请求的相关权限组的权限会向用户直接申请，并处理申请拒绝的逻辑
  /// iOS仅请求一次权限，Android如下：
  /// 1、初次检测某权限  弹出解释弹窗，n秒自动消失（可选,默认一直展示） 拒绝、允许后自动消息
  /// 2、权限被拒 弹出打开设置弹窗（可选,在没有权限不影响业务的地方建议关闭 如 定位、通知）

  ///返回值 如已有权限返回true, 否则 false
  static Future<bool> checkAndRequestPermission(
    BuildContext context,
    Permission permission, {
    bool showTipsDialog = true,
    String? tipsTitle,
    String? tipsContent,
    bool showOpenSetting = true,
    String? openSettingTips,
  }) async {
    bool isGranted = await PermissionHelper.instance()
        .checkPermissionsIsGranted(permission);

    if (isGranted) {
      return isGranted; //已获得授权
    }

    if (Platform.isAndroid && showTipsDialog && context.mounted) {
      Navigator.push(
        context,
        _PopRoute(
          child: PermissionCheckDialog(
            permissions: [permission],
            title: tipsTitle,
            tips: tipsContent,
          ),
        ),
      );
    }

    //1、直接申请
    isGranted = await PermissionHelper.instance().requestPermission(permission);
    if (PermissionCheckDialog.isShowingDialog) {
      await Future.delayed(const Duration(milliseconds: 300));
      if (context.mounted) {
        await PermissionCheckDialog.dismissPermissionDialog(context);
      }
    }

    if (isGranted) {
      return true;
    }

    if (Platform.isAndroid && showOpenSetting) {
      await Future.delayed(const Duration(milliseconds: 20));
      if (context.mounted) {
        var result = await Navigator.push(
          context,
          _PopRoute(
            child: OpenSettingDialog(
              permission: permission,
              tips: openSettingTips,
            ),
          ),
        );
        if (result) {
          return true;
        }
      }
    }
    return false;
  }

  ///检查权限是否都被授予
  Future<bool> checkPermissionsIsGranted(Permission permission) async {
    PermissionStatus status = await permission.status;
    if (Platform.isIOS) {
      return status.isGranted || status.isLimited;
    }
    return status.isGranted;
  }

  ///请求权限
  Future<bool> requestPermission(Permission permission) async {
    final status = await permission.request();
    if (Platform.isIOS) {
      return status.isGranted || status.isLimited;
    }

    return status.isGranted;
  }

  ///检查权限是否都被授予
  Future<bool> checkPermissionsGranted(List<Permission> permissions) async {
    for (var element in permissions) {
      var result = false;
      if (Platform.isIOS) {
        result =
            await element.status.isGranted || await element.status.isLimited;
      } else {
        result = await element.status.isGranted ? true : false;
      }
      if (result != true) {
        return false;
      }
    }
    return true;
  }

  ///检测权限是否可以动态申请
  Future<bool> shouldShowRequestPermissionRationale(
    Permission permission,
  ) async {
    bool shouldShowRequestPermissionRationale =
        await permission.shouldShowRequestRationale;
    if (!shouldShowRequestPermissionRationale) {
      shouldShowRequestPermissionRationale =
          shouldShowRequestPermissionRationale =
              await permission.status.isGranted;
    }
    return shouldShowRequestPermissionRationale;
  }
}

///动态权限检测对话框
class PermissionCheckDialog extends StatefulWidget {
  final List<Permission> permissions;
  final String? title;
  final String? tips;

  const PermissionCheckDialog({
    Key? key,
    required this.permissions,
    this.title,
    this.tips,
  }) : super(key: key);

  static bool isShowingDialog = false;

  static Future<dynamic> dismissPermissionDialog(BuildContext context) async {
    if (isShowingDialog) {
      isShowingDialog = false;
      return Navigator.pop(context);
    }
    return null;
  }

  @override
  State<StatefulWidget> createState() => PermissionCheckDialogState();
}

class PermissionCheckDialogState extends State<PermissionCheckDialog>
    with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    PermissionCheckDialog.isShowingDialog = true;
  }

  @override
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
    PermissionCheckDialog.isShowingDialog = false;
  }

  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    if (state == AppLifecycleState.resumed) {
      var hasGranted = await PermissionHelper.instance()
          .checkPermissionsGranted(widget.permissions);
      if (PermissionCheckDialog.isShowingDialog && context.mounted) {
        PermissionCheckDialog.isShowingDialog = false;
        Navigator.pop(context, hasGranted);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    String title = widget.title ?? "权限使用说明";
    String tips = widget.tips ?? "该功能需要您授予相关的权限，才可正常使用";
    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: () {
        PermissionCheckDialog.dismissPermissionDialog(context);
      },
      child: Scaffold(
        backgroundColor: Colors.black38,
        body: Container(
          alignment: Alignment.topCenter, //Alignment.center,
          padding: const EdgeInsets.only(top: 28),
          child: Container(
            width: double.maxFinite,
            margin: const EdgeInsets.symmetric(horizontal: 16),
            decoration: const BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.all(Radius.circular(8)),
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Container(
                  width: double.maxFinite,
                  padding: const EdgeInsets.only(left: 16, top: 16, right: 16),
                  child: Text(
                    title,
                    style: const TextStyle(fontSize: 16, color: Colors.black87),
                  ),
                ),
                Container(
                  width: double.maxFinite,
                  padding: const EdgeInsets.only(
                    left: 16,
                    top: 4,
                    right: 16,
                    bottom: 20,
                  ),
                  child: Text(
                    tips,
                    style: const TextStyle(fontSize: 14, color: Colors.black54),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

///引导设置打开权限对话框
class OpenSettingDialog extends StatefulWidget {
  const OpenSettingDialog({Key? key, required this.permission, this.tips})
    : super(key: key);

  final Permission permission;
  final String? tips;

  @override
  State<OpenSettingDialog> createState() => _OpenSettingDialogState();
}

class _OpenSettingDialogState extends State<OpenSettingDialog>
    with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
    if (state == AppLifecycleState.resumed) {
      var hasGranted = await PermissionHelper.instance()
          .checkPermissionsIsGranted(widget.permission);
      if (context.mounted) {
        Navigator.pop(context, hasGranted);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black54,
      body: Center(
        child: Container(
          width: MediaQuery.of(context).size.width - 60,
          decoration: const BoxDecoration(
            color: Colors.white,
            borderRadius: BorderRadius.all(Radius.circular(8)),
          ),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.only(
                  left: 15,
                  right: 15,
                  top: 30,
                  bottom: 50,
                ),
                child: Text(
                  widget.tips ?? "该功能需要到设置中授予相关权限，才可正常使用，请授予应用相关权限",
                  style: const TextStyle(fontSize: 16, color: Colors.black87),
                ),
              ),
              Divider(height: 1, thickness: 1, color: Colors.grey[300]),
              SizedBox(
                height: 45,
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    Expanded(
                      child: InkWell(
                        onTap: () => Navigator.pop(context, false),
                        child: const Center(
                          child: Text(
                            "取消",
                            style: TextStyle(
                              fontSize: 16,
                              color: Colors.black54,
                            ),
                          ),
                        ),
                      ),
                    ),
                    SizedBox(
                      height: 45,
                      width: 1,
                      child: VerticalDivider(
                        width: 1,
                        thickness: 1,
                        color: Colors.grey[300],
                      ),
                    ),
                    Expanded(
                      child: InkWell(
                        onTap: () async {
                          await openAppSettings();
                        },
                        child: const Center(
                          child: Text(
                            "去设置",
                            style: TextStyle(
                              fontSize: 16,
                              color: Colors.black87,
                            ),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class _PopRoute<int> extends PopupRoute {
  final Duration _duration = const Duration(milliseconds: 30);
  Widget child;

  _PopRoute({required this.child});

  @override
  bool get barrierDismissible => true;

  @override
  get barrierLabel => null;

  @override
  Widget buildPage(
    BuildContext context,
    Animation<double> animation,
    Animation<double> secondaryAnimation,
  ) {
    return child;
  }

  @override
  Duration get transitionDuration => _duration;

  @override
  Color? get barrierColor => null;
}
